﻿// -----------------------------------------------------------------------
// <copyright file="TransitionFunction.cs" company="">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace TheoryProject.Task1
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    public enum Direction
    {
        LEFT, RIGHT
    };

    public struct Transition
    {
        public int state;
        public int nextState;
        public char inputChar;
        public Direction direction;
        public char outputChar;
    };

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class TuringMachine
    {
        Transition[] transitions;
        public  List<char> tape;
        int head;
        int state;
        int[] finalStates;

        public TuringMachine(Transition[] transitions, List<char> tape, int[] finalS)
        {
            this.transitions = transitions;
            this.tape = tape;
            this.head = 0;
            this.state = 0;
            this.finalStates = finalS;
        }

        public Transition? GetTransition(char inputChar, int state)
        {
            for (int i = 0; i < transitions.Length; i++)
            {
                if ((transitions[i].state == state) && (transitions[i].inputChar == inputChar))
                {
                    return transitions[i];
                }
            }
            return null;
        }

        public bool Process()
        {
            Transition? nextTransition;
            while (true)
            {
                nextTransition = GetTransition(tape[head], state);
                
                if (nextTransition != null)
                {
                    Transition temp = (Transition)nextTransition;
                    
                        state = temp.nextState;
                        tape[head] = temp.outputChar;
                        if (temp.direction == Direction.LEFT)
                        {
                            head--;
                            if (head < 0)
                            {
                                tape.Insert(0, '\0');
                                head = 0;
                            }
                        }
                        else 
                        {
                            head++;
                            if (head == tape.Count)
                            {
                                tape.Insert(tape.Count, '\0');
                                head = tape.Count-1;
                            }
                        }
                        if (isFinalState(temp.nextState))
                        {
                            return true;
                        }
                }
                else
                {
                    return false;
                }
            }
        }

        public bool isFinalState(int state)
        {
            int length = finalStates.Length;
            for (int i = 0; i < length; i++)
            {
                if (state == finalStates[i])
                {
                    return true;
                }
            }
            return false;
        }
    }
}